package com.mjk.common.core.jdbc.service.plus.provider.abstractor;

import com.mjk.common.base.model.BaseEntity;
import com.mjk.common.base.model.BaseExample;
import com.mjk.common.core.jdbc.service.plus.provider.interfaces.IBeeProvider;
import com.mjk.common.core.jdbc.util.TableUtils;
import com.mjk.common.core.jdbc.util.provider.InsertSqlProvider;
import com.mjk.common.core.jdbc.util.provider.SelectSqlProvider;
import com.mjk.common.core.jdbc.util.provider.SqlProvider;
import com.mjk.common.core.jdbc.util.provider.UpdateSqlProvider;
import com.mjk.common.util.ObjectUtils;
import com.mjk.common.util.ReflectionUtils;
import com.mjk.common.util.StrUtils;
import org.apache.ibatis.jdbc.SQL;

import java.util.Map;

/**
 * 基于 Example 方式的 provider
 */
public interface IExampleProvider extends IBeeProvider {
    default String excuteSql(String sql) {
        return sql;
    }

    default String countByExample(Map<String, Object> map) {
        BaseExample example = (BaseExample) map.get("example");
        String whereSql = SelectSqlProvider.getQueryCondition(example);
        BaseEntity entity = SqlProvider.getEntityFromExample(example);
        String tableName = TableUtils.getTableName(entity);
        SQL sql = new SQL();
        if(ObjectUtils.isNotEmpty(whereSql)) {
            sql.SELECT("count(*)").FROM(tableName).WHERE(whereSql);
        }else {
            sql.SELECT("count(*)").FROM(tableName);
        }
        return sql.toString();
    }

    default String deleteByExample(Map<String, Object> map) {
        BaseExample example = (BaseExample) map.get("example");
        StrUtils.notNull(example, "example is null");
        BaseEntity entity = SqlProvider.getEntityFromExample(example);
        String tableName = TableUtils.getTableName(entity);
        String where = SelectSqlProvider.getQueryCondition(example);
        SQL sql = new SQL();
        if(ObjectUtils.isNotEmpty(where)) {
            sql.DELETE_FROM(tableName).WHERE(where);
        }else {
            sql.DELETE_FROM(tableName);
        }
        return sql.toString();
    }

    default String deleteByPrimaryKey(BaseEntity t) {
        String pramaryKey = SqlProvider.getPramaryKey(t);
        Object pramaryValue = ReflectionUtils.getFieldValue(t, pramaryKey);
        StrUtils.notNull(pramaryValue, "pramary key is null");
        String tableName = TableUtils.getTableName(t);
        return new SQL().DELETE_FROM(tableName).WHERE(pramaryKey+"="+pramaryValue).toString();
    }

    default String insert(Map<String, Object> map) {
        BaseEntity app = (BaseEntity) map.get("item");
        StrUtils.notNull(app, "app is null");
        String tableName = TableUtils.getTableName(app);
        return new SQL().INSERT_INTO(tableName).INTO_COLUMNS(InsertSqlProvider.getInsertFiled(app))
                .INTO_VALUES(InsertSqlProvider.getInsertFiledValue(app)).toString();

    }

    default String selectByExample(Map<String, Object> map) {
        BaseExample example = (BaseExample) map.get("example");
        StrUtils.notNull(example, "example is null");
        BaseEntity entity = SqlProvider.getEntityFromExample(example);
        String tableName = TableUtils.getTableName(entity);
        String where = SelectSqlProvider.getQueryCondition(example);
        String groupBy = SelectSqlProvider.getGroupSql(example);//groupby字段
        String orderBy = SelectSqlProvider.getOrderSql(example);
        SQL sql = new SQL();
        if(ObjectUtils.isNotEmpty(groupBy))
            sql.SELECT(SelectSqlProvider.getSelectFiledByOrder(entity, groupBy));
        else
            sql.SELECT(SelectSqlProvider.getSelectFiled(entity));
        sql.FROM(tableName);
        if(ObjectUtils.isNotEmpty(where))
            sql.WHERE(SelectSqlProvider.getQueryCondition(example));
        if(ObjectUtils.isNotEmpty(groupBy))
            sql.GROUP_BY(groupBy);
        if(ObjectUtils.isNotEmpty(orderBy)){
            sql.ORDER_BY(orderBy);
        }
        return sql.toString();
    }

    default String selectByPrimaryKey(Map<String, Object> map) {
        BaseEntity t = (BaseEntity) map.get("dto");
        String tableName = TableUtils.getTableName(t);
        String pramaryKey = SqlProvider.getPramaryKey(t);
        Object pramaryValue = ReflectionUtils.getFieldValue(t, pramaryKey);
        StrUtils.notNull(pramaryValue, "primat key is null");
        return new SQL().SELECT(SelectSqlProvider.getSelectFiled(t)).FROM(tableName).WHERE(pramaryKey + "=#{dto." + pramaryValue + "}").toString();
    }

    default String updateByPrimaryKeySelective(Map<String, Object> map) {
        BaseEntity entity = (BaseEntity) map.get("dto");
        StrUtils.notNull(entity, "dto is null");
        String tableName = TableUtils.getTableName(entity);
        String pramaryKey = SqlProvider.getPramaryKey(entity);
        return new SQL().UPDATE(tableName).SET(UpdateSqlProvider.getUpdateFiled(entity)).WHERE(pramaryKey + "=#{dto." + pramaryKey + "}").toString();
    }

    default String updateByExampleSelective(Map<String, Object> map) {
        BaseEntity app = (BaseEntity) map.get("dto");
        BaseExample example = (BaseExample) map.get("example");
        String tableName = TableUtils.getTableName(app);
        String where = SelectSqlProvider.getQueryCondition(example);
        SQL sql = new SQL();
        if(ObjectUtils.isNotEmpty(where)) {
            sql.UPDATE(tableName).SET(UpdateSqlProvider.getUpdateFiled(app)).WHERE(where);
        }else {
            sql.UPDATE(tableName).SET(UpdateSqlProvider.getUpdateFiled(app));
        }
        return sql.toString();
    }




    @Override
    default String getFiledLenght(String clazz, String length) {
        if (length.equals("0")) {
            return "";
        }
        if (ObjectUtils.isEmpty(length)) {
            return "";
        }
        return " ("+length+") ";
    }


}
